//
//  Player.m
//  Return Of The Lemi
//
//  Created by Paul Vishayanuroj on 11/2/09.
//  Copyright 2009 Cornell University. All rights reserved.
//

#import "Player.h"
#import "Layer_Creatures.h"

@implementation Player

@synthesize playerState;
@synthesize maxAmmo, remainingAmmo;
@synthesize walk;

+ (id) playerWithPos:(CGPoint)pos
{
	return [[[self alloc] initWithPos:pos] autorelease];
}

- (id) initWithPos:(CGPoint)pos
{
	if((self = [super init])) 
	{
		[self LoadActions];
		[self AnimateUnlock];
		
		// Set the initial pos
		[sprite setPosition:pos];
		
		// Set the walk vector
		walk = CGPointMake(CONST_LEMUR_WALK_SPEED, 0);
		
		ammoType = kumquatYellow;
		
		// Create the physics
		body = cpBodyNew(200.0f, INFINITY);
		
		body->p = cpv(pos.x, pos.y);
		
		cpVect verts[] = {
			cpv(-10, -43),
			cpv(-10, 30),
			cpv(-2, 30),
			cpv(-2, -43),
		};
		
		shape = cpPolyShapeNew(body, 4, verts, cpvzero);		
		shape->e = 0.9f; shape->u = 0.9f;
		shape->data = self;
		shape->collision_type = cTagPlayer; 
	}
	return self;
}

// Update function called every cycle
- (void) Update
{	
	switch (playerState) {
		case standing:
			
			break;
		case walking:
			// Add the stored walk vector to the sprite position
			sprite.position = ccpAdd(sprite.position, walk); 
			// Call to move the parallax node
			// SpriteManager -> Layer_Creatures -> ParallaxNode -> Scene_Game 
			[(Scene_Game *)spriteManager.parent.parent.parent Move:(CGPointMake(sprite.position.x, sprite.position.y))];			
			break;
		case throwing:
			if (!animateLock)
			{
				playerState = standing;
				[self Stand];
			}
			break;
		case spinning:
			if (!animateLock)
			{
				playerState = standing;
				[self Stand];
			}
			break;
		default:
			break;
	}
}

- (void) Stand
{
	playerState = standing;
	[sprite setDisplayFrame:@"lemur_walk" index:0];
	[sprite stopAllActions];
}

- (void) Walk
{
	playerState = walking;
	[sprite runAction: [RepeatForever actionWithAction:actionWalk]];
}

- (void) Flip
{
	walk = ccpMult(walk, -1.0f);
	[sprite runAction: [ScaleBy actionWithDuration:0.0f scaleX:-1 scaleY:1]];
}

- (void) Spin
{
	if (!animateLock)
	{
		playerState = spinning;
		animateLock = YES;
		[sprite runAction: [Sequence actions:actionSpin, actionUnlock, nil]];
	}
}

- (void) Throw
{
	if (!animateLock)
	{
		playerState = throwing;
		animateLock = YES;
		[sprite runAction: [Sequence actions:actionThrow, actionCreateKumquat, actionUnlock, nil]];
	}
}

- (void) FireKumquat
{
	[(Layer_Creatures *)spriteManager.parent fireMunition:(ammoType) position:sprite.position];
}

- (void) AnimateUnlock
{
	animateLock = NO;
}

- (void) LoadActions
{
	//spriteManager = [[AtlasSpriteManager spriteManagerWithFile: @"Lemur_Walk_Old.png"] retain];
	spriteManager = [[AtlasSpriteManager spriteManagerWithFile: @"Lemur_Spritesheet.png"] retain];
	
	// The default sprite
	sprite = [[AtlasSprite spriteWithRect:(CGRectMake(0, 0, CONST_FRAME_SIZE, CONST_FRAME_SIZE)) spriteManager:self.spriteManager] retain];

	// Create the animation objects with delays between each frame
	AtlasAnimation *animationWalk = [AtlasAnimation animationWithName: @"lemur_walk" delay: CONST_LEMUR_WALK_ANIMATION_DELAY];
	AtlasAnimation *animationSpin = [AtlasAnimation animationWithName: @"lemur_spin" delay: CONST_LEMUR_SPIN_ANIMATION_DELAY];
	AtlasAnimation *animationThrow = [AtlasAnimation animationWithName: @"lemur_throw" delay: CONST_LEMUR_THROW_ANIMATION_DELAY];
	
	// Add the walk animations from the sprite sheet
	for (int i = 0; i < CONST_LEMUR_NUM_WALK_FRAMES; i++)
	{
		int x = i % CONST_NUM_FRAMES_PER_SIDE; // Traverse the grid
		int y = i / CONST_NUM_FRAMES_PER_SIDE; 
		[animationWalk addFrameWithRect:(CGRectMake(x * CONST_FRAME_SIZE, y * CONST_FRAME_SIZE, CONST_FRAME_SIZE, CONST_FRAME_SIZE))];
	}
	
	// Add the spin animations from the sprite sheet
	for (int i = 0; i < CONST_LEMUR_NUM_SPIN_FRAMES; i++)
	{
		[animationSpin addFrameWithRect:(CGRectMake(i * CONST_FRAME_SIZE, 2 * CONST_FRAME_SIZE, CONST_FRAME_SIZE, CONST_FRAME_SIZE))];
	}

	// Add the throw animations from the sprite sheet
	for (int i = 0; i < CONST_LEMUR_NUM_ATTACK_FRAMES; i++)
	{
		[animationThrow addFrameWithRect:(CGRectMake(i * CONST_FRAME_SIZE, 3 * CONST_FRAME_SIZE, CONST_FRAME_SIZE, CONST_FRAME_SIZE))];
	}
	
	// Associate the animation with the sprite in case we need it later
	[sprite addAnimation: animationWalk];
	[sprite addAnimation: animationSpin];
	[sprite addAnimation: animationThrow];
	
	actionWalk = [[Animate actionWithAnimation: animationWalk] retain];
	actionSpin = [[Animate actionWithAnimation: animationSpin] retain];
	actionThrow = [[Animate actionWithAnimation: animationThrow] retain];
	actionCreateKumquat = [[CallFunc actionWithTarget:self selector:@selector(FireKumquat)] retain]; 
	actionUnlock = [[CallFunc actionWithTarget:self selector:@selector(AnimateUnlock)] retain];

	[spriteManager addChild:sprite z:1 tag:kTagSprite];
}

- (void) dealloc
{
	[maxAmmo release];
	[remainingAmmo release];
	[spriteManager release];
	[sprite release];
	[actionStand release];
	[actionWalk release];
	[actionSpin release];
	[actionThrow release];
	[actionCreateKumquat release];
	[actionUnlock release];
	[super dealloc];
}


@end
